/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entity;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import view.PlayerLattice;

/**
 *
 * @author laarguelless
 */
public class Player {

    /**
     * Cooperar = 0 Traicionar = 1
     */
    private int lastMov;
    private int currentMov;
    private int[] strategy;
    private int[] nextStrategy;
    private int i;
    private int j;
    private List<Player> neighbors;
    private int payoff;
    private PlayerLattice lattice;
    private int generations;

    public Player() {
        lastMov = 0;
        currentMov = 0;
        strategy = null;
        i = 0;
        j = 0;
        neighbors = new ArrayList<Player>();
        payoff = 0;
        lattice = null;
        generations = 0;
    }

    public Player(int curMov, int[] strat, int i, int j, int gen, PlayerLattice lattice) {
        currentMov = curMov;
        lastMov = curMov;
        strategy = strat;
        this.i = i;
        this.j = j;
        neighbors = new ArrayList<Player>();
        payoff = 0;
        this.lattice = lattice;
        generations = gen;
    }

    public int getRow() {
        return i;
    }

    public int getCol() {
        return j;
    }

    public void setPayOff(int payOff) {
        this.payoff = payOff;
    }

    public int getPayOff() {
        return this.payoff;
    }

    public void clearPayOff() {
        this.payoff = 0;
    }

    public int[] getStrategy() {
        return strategy;
    }

    public void setNeighbor(Player neighbor) {
        neighbors.add(neighbor);
    }

    public Player getNeighbor(int index) {
        return neighbors.get(i);
    }

    public List<Player> getNeigbors() {
        return neighbors;
    }

    public void changeColor(int behaviour) {
        lattice.changeColor(behaviour);
    }

    /**
     * Da el último movimiento *
     */
    public int getLastBehaviour() {
        return lastMov;
    }

    /*
     * Calcula el próximo movimiento basado en su movimiento pasado y en el de
     * sus vecinos...
     */
    public void calculateNextBehaviour() {

        int index;
        int othersBehaviour;
        int limit = (lastMov == 0) ? 2 : 1;
        //Random random = new Random();
        int tokens = 4;
        for (Player ne : neighbors) {
            if (ne.getLastBehaviour() == 1) {
                tokens--;
            }
        }

        if (tokens < limit) {
            /**
             * El comportamiento de los vecinos en general fue de traición *
             */
            othersBehaviour = 1;
        } else {
            /**
             * El comportamiento de los vecinos en general fue de cooperación *
             */
            othersBehaviour = 0;
        }
        if (lastMov == 0 && othersBehaviour == 0) {
            currentMov = strategy[0];
        } else if (lastMov == 0 && othersBehaviour == 1) {
            currentMov = strategy[1];
        } else if (lastMov == 1 && othersBehaviour == 0) {
            currentMov = strategy[2];
        } else if (lastMov == 1 && othersBehaviour == 1) {
            currentMov = strategy[3];
        }
    }

    /**
     * Hace el siguiente movimiento
     */
    public void doNextMovement() {

        /**
         * Basado en el comportamiento acutal y el anterior cambia de color *
         */
        if (currentMov == 0 && lastMov == 0) {
            changeColor(0);
        } else if (currentMov == 1 && lastMov == 0) {
            changeColor(1);
        } else if (currentMov == 0 && lastMov == 1) {
            changeColor(2);
        } else if (currentMov == 1 && lastMov == 1) {
            changeColor(3);
        }

        /**
         * Guardo el comportamiento actual en el anterior*
         */
        lastMov = currentMov;
        /**
         * reinicio el comportamiento actual para que se calcule de nuevo en el
         * otro turno *
         */
        currentMov = -1;
    }

    public void calculateNextStrategy() {
        double nePayOff;
        nextStrategy = strategy;
        for (Player ne : neighbors) {
            nePayOff = ne.getAveragePayOff();
            if (getAveragePayOff() < nePayOff) {
                nextStrategy = ne.getStrategy();
            }
        }
    }

    public void setStrategy() {
        strategy = nextStrategy;
        nextStrategy = null;
    }

    public void setLabel(String label) {
        lattice.chanceStrategy(label);
    }

    public double getAveragePayOff() {
        return payoff / generations;
    }
}
